using System;
using System.Collections;
using System.Configuration;
using System.Collections.Specialized;
using System.Runtime.Serialization;

using Colossus.Tools;

namespace Colossus.Diagnostics.Logging {

	/// <summary>
	/// Encapsulates several logging engines so they can be fired out all at once.
	/// </summary>
	public class LoggingManager : LoggingBase, IDisposable {

		public LoggingManager(string name) : base(name) {
			Instances.Add(this);
		}
		public LoggingManager(string name, LogDetailLevel infoLevel) : base(name, infoLevel) {
			Instances.Add(this);
		}
		~LoggingManager() {
			Dispose(false);
		}

		private static LoggedManagerConfiguration _configuration;
		private static ListDictionary _modules;
		private static ArrayList _instances;

		public static ArrayList Instances {
			get {
				if (_instances == null)
					_instances = new ArrayList();
				return _instances;
			}
		}

		public LoggedManagerConfiguration Configuration {
			get {
				if (_configuration == null)
					_configuration = new LoggedManagerConfiguration(this.GetType().FullName + "." + Name);
				return _configuration;
			}
		}

		public ListDictionary Modules {
			get {
				if (_modules == null)
					InitializeModules();
				return _modules;
			}
		}

		public void InitializeModules() {
			_modules = new ListDictionary();

			LoggingEmail _mail;
			LoggingEvent _events;
			LoggingFile _log;

			_mail = new LoggingEmail("EmailNotification", LogDetailLevel.Error);
			_events = new LoggingEvent("EventLog", LogDetailLevel.Warning);
			_log = new LoggingFile("DiskLog", LogDetailLevel.Info);

			_log.FilePath = Configuration.LogFilePath; //"C:\Colossus.Tools.Exceptions.log";
			_mail.From = Configuration.EmailNotificationFrom; //"systemnotification@playground.local";
			_mail.To = Configuration.EmailNotificationTo; //"thomas.carpe@playground.local";

			Modules.Add("Email", _mail);
			Modules.Add("EventLog", _events);
			Modules.Add("DiskLog", _log);
			//Modules.Add("DatabaseLog", events);
		}

		public override void Open() {
			foreach (string key in Modules) {
				if (((LoggingBase)Modules[key]).CanOpen)
					((LoggingBase)Modules[key]).Open();
			}
		}

		public override void Close() {
			foreach (string key in Modules) {
				if (((LoggingBase)Modules[key]).CanOpen)
					((LoggingBase)Modules[key]).Close();
			}
		}

		public override void Initialize() {
			if (_modules == null)
				InitializeModules();
		}

		public override void Write(LogDetailLevel infoLevel, string text) {
			foreach (string key in Modules) {
				((LoggingBase)Modules[key]).Write(infoLevel, text);
			}
		}

		public override void Write(LogDetailLevel infoLevel, string text, string category) {
			foreach (string key in Modules) {
				((LoggingBase)Modules[key]).Write(infoLevel, text, category);
			}
		}

		public override void Write(LogItem info) {
			foreach (string key in Modules) {
				((LoggingBase)Modules[key]).Write(info);
			}
		}

		#region IDisposable Members

		private bool _isDisposed;

		protected override void Dispose(bool explicitlyCalled) {
			if (!_isDisposed) {
				base.Dispose(explicitlyCalled);
				Instances.Remove(this);
				if (Instances.Count == 0) {
					_modules.Clear();
					_modules = null;
					_instances = null;
				}
				_configuration = null;
				_isDisposed = true;
			}
		}

		#endregion

	} // class

	/// <summary>
	/// Contains the properties that are read to determine how LoggingException will behave.
	/// </summary>
	public class LoggedManagerConfiguration {

		private string configPrefix;

		public LoggedManagerConfiguration(string parentTypeName) {
			this.configPrefix = parentTypeName;
		}

		public string LogFilePath {
			get { return ConfigurationManager.AppSettings[configPrefix + ".LogFilePath"]; }
		}
		public string EmailNotificationTo {
			get { return ConfigurationManager.AppSettings[configPrefix + ".EmailNotificationTo"]; }
		}
		public string EmailNotificationFrom {
			get { return ConfigurationManager.AppSettings[configPrefix + ".EmailNotificationFrom"]; }
		}

	} // class

} // namespace
